package com.nanyang.tms.manager.forecast.handler;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.nanyang.common.core.flow.context.TransHandlerContext;
import com.nanyang.common.core.flow.handler.AbstractTransHandler;
import com.nanyang.tms.common.dict.TmsExceptionEnum;
import com.nanyang.tms.common.exception.TmsManagerException;
import com.nanyang.tms.common.util.TmsExceptionUtil;
import com.nanyang.tms.dao.company.CompanyDao;
import com.nanyang.tms.dao.saleprice.SalePartCityDao;
import com.nanyang.tms.dao.saleprice.SalePartCountyDao;
import com.nanyang.tms.dao.saleprice.SalePartZipcodeDao;
import com.nanyang.tms.dao.saleprice.SalePriceDiscountDao;
import com.nanyang.tms.dao.saleprice.SaleWeightRecordDao;
import com.nanyang.tms.domain.forecast.context.CalculateFreightContext;
import com.nanyang.tms.domain.saleprice.SalePricePartCountyVO;
import com.nanyang.tms.domain.saleprice.SalePriceWeightRecordVO;


@Component
public class CalculateFreightHandler extends AbstractTransHandler {
	@Autowired
	private SalePartCountyDao salePartCountyDao;
	@Autowired
	private SalePartCityDao salePartCityDao;
	@Autowired
	private SalePartZipcodeDao salePartZipcodeDao;
	@Autowired
	private SaleWeightRecordDao saleWeightRecordDao;
	@Autowired
	private CompanyDao companyDao;
	@Autowired
	private SalePriceDiscountDao salePriceDiscountDao;

	@Override
	public boolean isAsync() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean handle(TransHandlerContext context) {
		CalculateFreightContext calculateFreightContext = (CalculateFreightContext) context
				.getInnerContext(CalculateFreightContext.class);
		
		
		try {
			// 根据产品编码和国家码 获取分区信息 一个分区中 相同的国家只有一个
			SalePricePartCountyVO salePricePartCountry = salePartCountyDao.getSalePricePartCountry(
					calculateFreightContext.getSaleProductCode(), calculateFreightContext.getCountyCode());
			if (salePricePartCountry == null) {
				throw new TmsManagerException(TmsExceptionEnum.PART_RULE_IS_NOT_EXIST.getCode(),
						TmsExceptionEnum.PART_RULE_IS_NOT_EXIST.getMessage());
			}
			// 分区中是城市方案的话 查询国家是否有对应的城市 没有的话 抛出异常
			if (salePricePartCountry.getSchemeTypeCode().equals("city_scheme")) {
				Integer count = salePartCityDao.countParctCity(salePricePartCountry.getPartCountyCode(),
						calculateFreightContext.getCityCode());
				if (count == 0) {
					throw new TmsManagerException(TmsExceptionEnum.PART_RULE_IS_NOT_EXIST.getCode(),
							TmsExceptionEnum.PART_RULE_IS_NOT_EXIST.getMessage());
				}
				// 分区中是邮编方案的话 查询国家是否有对应的邮编  没有的话 抛出异常
			} else if (salePricePartCountry.getSchemeTypeCode().equals("zipcode_scheme")) {
				Integer count = salePartZipcodeDao.countPartZipcode(salePricePartCountry.getPartCountyCode(),
						calculateFreightContext.getCityCode());
				if (count == 0) {
					throw new TmsManagerException(TmsExceptionEnum.PART_RULE_IS_NOT_EXIST.getCode(),
							TmsExceptionEnum.PART_RULE_IS_NOT_EXIST.getMessage());
				}
			} else {
				List<SalePriceWeightRecordVO> weightRecords = saleWeightRecordDao
						.getWeightRecord(salePricePartCountry.getSaleCode(), salePricePartCountry.getPartCode());
				validateWeightRecords(weightRecords);
				AtomicInteger index = new AtomicInteger(-1);
				SalePriceWeightRecordVO matchWeightRecord = weightRecords.stream().filter(x -> {
					index.getAndIncrement();
					if (calculateFreightContext.getTotalChargeWeight().compareTo(x.getWeightStart()) == 1
							&& (calculateFreightContext.getTotalChargeWeight().compareTo(x.getWeightEnd()) == 0
									|| calculateFreightContext.getTotalChargeWeight().compareTo(x.getWeightEnd()) == -1)) {
						return true;
					} else {
						return false;
					}
				}).findFirst().get();
				//计算运费
				BigDecimal amount = calFreight(matchWeightRecord, index.get(), calculateFreightContext.getTotalChargeWeight(), weightRecords);
				//计算折后运费
				calDiscount(calculateFreightContext.getCompanyCode(),calculateFreightContext.getSaleProductCode(),amount);
				calculateFreightContext.setAmount(amount);
			}
			return true;
		} catch (Exception e) {
			throw TmsExceptionUtil.wrapException(e);
		}
		
	}
   @SuppressWarnings("unused")
private void calDiscount(String companyCode,String saleProductCode,BigDecimal amount){
		//计算折扣
		String levelCode=companyDao.getCompanyLevel(companyCode);
	    if(StringUtils.isEmpty(levelCode)){
	    	throw new TmsManagerException(TmsExceptionEnum.COMPANY_IS_NOT_EXIST.getCode(),
					TmsExceptionEnum.COMPANY_IS_NOT_EXIST.getMessage());
	    }
	   BigDecimal disCount=  salePriceDiscountDao.getDiscount(saleProductCode, levelCode);
	   if(disCount!=null){
		   amount=amount.multiply(disCount.divide(new BigDecimal(10)));
	   }
   }
	@SuppressWarnings("unused")
	private void validateWeightRecords(List<SalePriceWeightRecordVO> weightRecords) {
		for (int i = 0; i < weightRecords.size(); i++) {
			if (i == 0) {
				if (weightRecords.get(i).getChargingCode().equals("xdj")
						|| weightRecords.get(i).getChargingCode().equals("xjdj")) {
					throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
							TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
				}
			} else if (i > 0 && i < weightRecords.size() - 1) {
				if (weightRecords.get(i).equals("xdj")) {
					// 单价、续阶单价、续单价
					if (weightRecords.get(i - 1).equals("dj") || weightRecords.get(i - 1).equals("xdj")
							|| weightRecords.get(i - 1).equals("xjdj")) {
						throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
								TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
					}
					if (weightRecords.get(i + 1).equals("xdj") || weightRecords.get(i + 1).equals("xjdj")) {
						throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
								TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
					}
				}
				if (weightRecords.get(i).equals("xjdj")) {
					// 单价、续阶单价、续单价
					if (weightRecords.get(i - 1).equals("dj") || weightRecords.get(i - 1).equals("xdj")) {
						throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
								TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
					}
					if (weightRecords.get(i + 1).equals("xdj")) {
						throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
								TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
					}
				}
			} else {
				if (weightRecords.get(i).equals("xdj")) {
					// 单价、续阶单价、续单价
					if (weightRecords.get(i - 1).equals("dj") || weightRecords.get(i - 1).equals("xdj")
							|| weightRecords.get(i - 1).equals("xjdj")) {
						throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
								TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
					}
				}
				if (weightRecords.get(i).equals("xjdj")) {
					// 单价、续阶单价、续单价
					if (weightRecords.get(i - 1).equals("dj") || weightRecords.get(i - 1).equals("xdj")) {
						throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
								TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
					}
				}
			}

		}
	}

	@SuppressWarnings("unused")
	private BigDecimal calFreight(SalePriceWeightRecordVO weightRecord, Integer index, BigDecimal totalChargeWeight,
			List<SalePriceWeightRecordVO> weightRecords) {
		if (weightRecord.getChargingCode().equals("dj")) {
			return weightRecord.getPrice().multiply(totalChargeWeight.divide(weightRecord.getWeightCharging()));
		} else if (weightRecord.getChargingCode().equals("zj")) {
			return weightRecord.getPrice();
		} else if (weightRecord.getChargingCode().equals("xdj")) {
			// 续单价费用计算公式 ：首重+(计费重-weightstart)*续单价
			if(weightRecords.get(index - 1).getChargingCode().equals("zj")){
				return weightRecords.get(index - 1).getPrice().add(weightRecord.getPrice().multiply(totalChargeWeight.subtract(weightRecord.getWeightStart()).divide(weightRecord.getWeightCharging())));
			}else{
				throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
						TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
			}
		} else if (weightRecord.getChargingCode().equals("xjdj")) {
			// 续阶单价费用计算公式 ：首重+(计费重-weightstart)*续阶单价+(weightend-weightstart)*续阶单价
			BigDecimal tmp= weightRecord.getPrice().multiply(totalChargeWeight.subtract(weightRecord.getWeightStart()).divide(weightRecord.getWeightCharging()));
			for(int i=index-1 ;i>=0;i--){
				if(weightRecords.get(i).getChargingCode().equals("zj")){
					return tmp.add(weightRecords.get(i).getPrice());
				}else if (weightRecords.get(i).getChargingCode().equals("xjdj")){
					tmp=tmp.add(weightRecords.get(i).getPrice().multiply(weightRecord.getWeightEnd()
							.subtract(weightRecord.getWeightStart()).divide(weightRecord.getWeightCharging())));
				}else{
					throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
							TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
				}
			}
			return tmp;
		} else{
			throw new TmsManagerException(TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getCode(),
					TmsExceptionEnum.CHARGECODE_RULE_IS_ERROR.getMessage());
		}
	}

}
